/******************************************************************************
秋夜静，独坐对残灯。
啼笑非非谁识我，坐行梦梦尽缘君，何所慰消沉。
风卷雨，雨复卷侬心。
心似欲随风雨去，茫茫大海任浮沉。
无爱亦无恨。
******************************************************************************/
#include "kbRGB.h"
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

/*************************************************************************************************\
|        Bloom [9]                                                                                |
\*************************************************************************************************/
//struct kbRGB_Flower {
//    //hsv_t hsv;
////    float hue;
////    float speed_mult;// = 1.f;
//    uint32_t hue:22;
//    uint32_t speed_mult:10;// = 1.f;
//};
//static struct kbRGB_Flower flowers[21*21];
#define flowers kbrgb_Params.Random_flowers
#if 0
static hsv_t RandomHSVColor()
{
    hsv_t hsv;

    hsv.hue = rand() % 360;
    hsv.saturation = 255;
    hsv.value = 255;

    return hsv;
}
#endif
static void Bloom_UpdateFlowers(const uint16_t len_max)
{
    float delta = (float) kbRGB_Speed / (float) kbRGB_FPS;

    for(unsigned int i = 0; i < (len_max); i++)
    {
        struct kbRGB_Flower* flower = &flowers[i];
        flower->hue += (flower->speed_mult * delta);
        //flower->hsv.hue = (int) flower->hue % 360;
    }
}


static void Bloom_Reset(void)
{
    //flowers.clear();
    memset(flowers, 0x000, sizeof(flowers));

    //for(ControllerZone* controller_zone: controller_zones)
    {
        //std::vector<Flower> zone_flowers;

        for(unsigned int i = 0; i < (sizeof(flowers)/sizeof(flowers[0])); i++)
        {
            struct kbRGB_Flower* flower = &flowers[i];
            //flower->hsv = /*ColorUtils::*/RandomHSVColor();
            //flower->hue = flower->hsv.hue;
            flower->hue = (rand() % 360)<<kbRGB_PRE_BIT;
            //flower->speed_mult = ((double) rand() / (RAND_MAX)) + 1;
            flower->speed_mult = (rand()&kbRGB_PRE_MAX) + kbRGB_PRE_MAX;
            //flower->speed_mult = 1.f;
            //zone_flowers.push_back(flower);
        }

        //flowers.push_back(zone_flowers);
    }
}
void kbRGB_Bloom_Init(void)    // 花朵
{
    kbrgb_Params.Speed = 50;
    kbrgb_Params.Slider2Val = 30;
    Bloom_Reset();
}
void kbRGB_Bloom(const uint16_t cols, const uint16_t rows)    // 花朵
{
    const uint16_t len_max = cols*rows;
    hsv_t hsv;
    hsv.saturation = 255;
    hsv.value = 255;

    Bloom_UpdateFlowers(len_max);
    for (uint16_t col_id = 0; col_id < cols; col_id++)
    {
        for (uint16_t row_id = 0; row_id < rows; row_id++)
        {
           int idx = (row_id * cols) + col_id;
           //uint32_t color = hsv2rgb(&flowers[idx].hsv);
           //hsv.hue = (int) flowers[idx].hue % 360;
           hsv.hue = (flowers[idx].hue>>kbRGB_PRE_BIT) % 360;
           uint32_t color = hsv2rgb(&hsv);
           kbRGB_pset(col_id, row_id, color);
        }
    }
}

/*************************************************************************************************\
|        Lightning [9]                                                                              |
\*************************************************************************************************/
enum lightning_mode_value
{
    WHOLE_ZONE  = 0,
    PER_LED     = 1
};
//static struct kbRGB_Lightning_t Lightnings[LightningsSizeMax];
////static uint8_t LightningsSize=0;
//static enum lightning_mode_value lightning_mode = WHOLE_ZONE;//WHOLE_ZONE;

#define Lightnings        kbrgb_Params.Random_Lightning.Lightnings
#define lightning_mode    kbrgb_Params.Random_Lightning.mode

//static void Lightning_OnControllerZonesListChanged(void)
//{
//    //Lightnings.clear();
//    memset(&Lightnings, 0x00, sizeof(Lightnings));

//    //for(ControllerZone* controller_zone: controller_zones)
//    {
//        //hsv_t leds;

//        for(unsigned int i = 0; i < 41*41; i++)
//        {
//            hsv_t* lightning;

//            lightning = &Lightnings[i];
//            lightning->value = 0;
//            lightning->hue = 0;//UserHSV.hue;
//            lightning->saturation = 0;//UserHSV.saturation;
//            //leds.push_back(lightning);
//        }

//        //Lightnings[controller_zone] = leds;
//    }
//}
void kbRGB_Lightning_Init(void)    // 闪电
{
    kbrgb_Params.Speed = 20;
    kbrgb_Params.Slider2Val = 10;
    memset(&Lightnings, 0x00, sizeof(Lightnings));
    lightning_mode = PER_LED;
}
static uint32_t Lightning_TriggerLightning(const int n, const uint16_t len_max)
{
    int Decay = kbrgb_Params.Slider2Val;
    uint16_t index=0;
    uint16_t id;

    float decrease = 1 + Decay/(float) kbrgb_Params.FPS;

    //unsigned int mod = (lightning_mode == WHOLE_ZONE) ? 1000 : 1000 * 41*41;//z->leds_count();
    unsigned int mod = (lightning_mode == WHOLE_ZONE) ? 900 : 900 * len_max;//z->leds_count();

    id = n+1;
    for(index=0; index<LightningsSizeMax; index++)
    {
        // Serach
        if(id==Lightnings[index].id) break;
    }
    if(WHOLE_ZONE==lightning_mode) index = 0;
    if(index<LightningsSizeMax)
    {
        //printf("[%s--%d] index:%3d n:%3d", __func__, __LINE__, index, n);
        //fflush(stdout);
        //    Lightnings[n].value = ((unsigned int)(rand() % mod)) < kbrgb_Params.Speed ?
        //                std::min<unsigned char>(255, RandomColorsEnabled ? 255: UserHSV.value) :
        //                Lightnings[z][n].value > 0 ?  Lightnings[z][n].value / decrease : 0;
            Lightnings[index].hsv.value = ((unsigned int)(rand() % mod)) < kbrgb_Params.Speed ?
                        255 : Lightnings[index].hsv.value > 0 ?  Lightnings[index].hsv.value / decrease : 0;

            //if(RandomColorsEnabled)
            {
                if(Lightnings[index].hsv.value == 0)
                {
                    //Lightnings[index].hsv.hue = rand() % 360;
                    //Lightnings[index].hsv.saturation = rand() % 255;
                    Lightnings[index].id = 0;//rand() % len_max;
                }
            }
        //    else
        //    {
        //        Lightnings[z][n].hue = UserHSV.hue;
        //        Lightnings[z][n].saturation = UserHSV.saturation;
        //    }

            return (hsv2rgb(&Lightnings[index].hsv));
    }
    if(0==(rand() % (20*len_max)))
    {
        for(index=0; index<LightningsSizeMax; index++)
        {
            // Empty
            if(0==Lightnings[index].id)
            {
                Lightnings[index].hsv.value = 255;
                Lightnings[index].hsv.hue = rand() % 360;
                Lightnings[index].hsv.saturation = rand() % 255;
                Lightnings[index].id = rand() % len_max;
                break;
            }
        }
    }
    hsv_t hsv;
    hsv.hue = 0;
    hsv.saturation = 0;
    hsv.value = 0;
    //return 0x00;
    return (hsv2rgb(&hsv));
}

void kbRGB_Lightning(const uint16_t cols, const uint16_t rows)    // 闪电
{
    const uint16_t len_max = cols*rows;
    if(lightning_mode == WHOLE_ZONE)
    {
        uint32_t color = Lightning_TriggerLightning(0, 1);
        for (uint16_t col_id = 0; col_id < cols; col_id++)
        {
            for (uint16_t row_id = 0; row_id < rows; row_id++)
            {
               kbRGB_pset(col_id, row_id, color);
            }
        }
    }
    else if(lightning_mode == PER_LED)
    {
        for (uint16_t col_id = 0; col_id < cols; col_id++)
        {
            for (uint16_t row_id = 0; row_id < rows; row_id++)
            {
                uint16_t id = row_id*cols+col_id;
                uint32_t color = Lightning_TriggerLightning(id, len_max);
                kbRGB_pset(col_id, row_id, color);
            }
        }
    }
}
